package com.zenika.zentracker.spring;

import org.springframework.aop.scope.ScopedProxyFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;

public class WebZenTrackerConfigurer extends ZenTrackerConfigurer {

    private String sessionAttributeIdentifier;
    
    public static final String REQUEST_STATISTICS_BEAN = "zenTrackerRequestStatistics";
    
    public static final String REQUEST_SCOPE_TARGET_BEAN = "scopedTarget.zenTrackerRequestStatistics";
    
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactoryToProcess) throws BeansException {
        super.postProcessBeanFactory(beanFactoryToProcess);
        
        GenericBeanDefinition targetBeanDefinition = new GenericBeanDefinition();
        targetBeanDefinition.setBeanClass(HttpRequestInfoBean.class);
        targetBeanDefinition.setScope("request");
        targetBeanDefinition.setAttribute("org.springframework.aop.framework.autoproxy.AutoProxyUtils.preserveTargetClass", Boolean.TRUE);
        if (sessionAttributeIdentifier != null) {
            targetBeanDefinition.getPropertyValues().addPropertyValue(new PropertyValue("sessionAttributeIdentifier", sessionAttributeIdentifier));    
        }

        RootBeanDefinition beanDefinition = new RootBeanDefinition();
        beanDefinition.setBeanClass(ScopedProxyFactoryBean.class);
        beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
        beanDefinition.getPropertyValues().addPropertyValue(new PropertyValue("targetBeanName", REQUEST_SCOPE_TARGET_BEAN));
        
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) beanFactoryToProcess;
        
        defaultListableBeanFactory.registerBeanDefinition(REQUEST_SCOPE_TARGET_BEAN, targetBeanDefinition);
        defaultListableBeanFactory.registerBeanDefinition(REQUEST_STATISTICS_BEAN, beanDefinition);
    }

    public void setSessionAttributeIdentifier(String sessionAttributeIdentifier) {
        this.sessionAttributeIdentifier = sessionAttributeIdentifier;
    }

}
